package com.jbp.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.hash.Hashing;
import com.jbp.exception.RRException;
import com.jbp.model.Identify;
import com.jbp.redis.RedisConfigService;
import com.jbp.utils.HttpClient;
import com.jbp.utils.HttpClient4Utils;
import com.jbp.utils.UUIDUtil;
import org.apache.commons.io.Charsets;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
public class TencentIdentifyService {
    @Autowired
    private RedisConfigService redisConfigService;

    final static String appId = "TIDA4ZRw";
    final static String secret = "YAHMBRmCfz4qT3HhJ8KloSA0r6XHCVhprCg7MhrG0rgNUDt2K3oltHVHRBPJY40g";
//    正式
//    final static String appId = "IDAZYPQk";
//    final static String secret = "VzyUktoaKdGSeVC8TkuesnSAAxbtCEx9MsChRz1UReZWRFl6S4EITCkQNcDSlCWk";

    final static String accessTokenKey = "tencent:identify:accessTokenKey";
    final static String accessTicket = "tencent:identify:signTicket";


    public String getTicketFromCache(){
        String ticket = (String) redisConfigService.get(accessTicket);
        if (ticket==null) {
            ticket = cacheTicket();
        }
        return ticket;
    }

    public String cacheTicket() {
        String ticket = getSignTicket();
        redisConfigService.set(accessTicket, ticket, 60*100L);
        return ticket;
    }


    public String getSignTicket(){
        return getTicket("SIGN", 0);
    }

    public String getNonceTicket(int userId){
        return getTicket("NONCE", userId);
    }

    public String getTicket(String type, int userId){
        try {
            String token = getAccessTokenKeyFromCache();
//            String token = "WAA0f-dGGlQHTVClazkxtmW6FX_nRhpUB01QpWs5MbZluhXIwom-PIfzyiLM6iBoFKT-U4rcBzeZ1viPXMCRJg4-ow";
            String url = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/api_ticket";
            HashMap<String, Object> params = new HashMap<>();
            params.put("app_id", appId);
            params.put("access_token", token);
            params.put("type", type);
            params.put("version", "1.0.0");
            if ("NONCE".equalsIgnoreCase(type)) {
                params.put("user_id", userId+"");
            }

            String result = HttpClient.doGetWithParam(params, url);
//            System.out.println("getTicket=="+result);
            JSONObject jsonObject = JSON.parseObject(result);
            if ("0".equalsIgnoreCase(jsonObject.getString("code"))) {
                return jsonObject.getJSONArray("tickets").getJSONObject(0).getString("value");
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public String getAccessTokenKeyFromCache(){
        String token = (String) redisConfigService.get(accessTokenKey);
        if (token==null) {
            token = cacheAccessToken();
        }
        return token;
    }

    public String cacheAccessToken() {
        String accessToken = getAccessToken();
        redisConfigService.set(accessTokenKey, accessToken, 60*100L);
        return accessToken;
    }

    public String getAccessToken(){
        try {
            String url = "https://miniprogram-kyc.tencentcloudapi.com/api/oauth2/access_token";
            HashMap<String, Object> params = new HashMap<>();
            params.put("app_id", appId);
            params.put("secret", secret);
            params.put("grant_type", "client_credential");
            params.put("version", "1.0.0");

            String result = HttpClient.doGetWithParam(params, url);
            System.out.println("==getAccessToken="+result);
             JSONObject jsonObject = JSON.parseObject(result);
            if ("0".equalsIgnoreCase(jsonObject.getString("code"))) {
                return jsonObject.getString("access_token");
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
//        String accessToken = new TencentIdentifyService().getAccessToken();
//        System.out.println(accessToken);
//        String ticket = new TencentIdentifyService().getTicket();
//        System.out.println(ticket);
        // chyvtGazRZvSjthyeLZRLPYE8h5yVcOclaLxAh7d8DGyLy3E03sCQRUcarKz47r9

        Identify identify = new Identify();
        identify.setUserId(12345678);
        identify.setOrderNo("12345678_23244342");
        identify.setRealName("李长椿");
        identify.setIdNumber("421003198910143516");
//        Map<String, Object> map = createOrder(identify);
//        if (map!=null) {
//            for (Map.Entry<String, Object> entry : map.entrySet()) {
//                System.out.println(entry.getKey()+":"+entry.getValue());
//            }
//        }
    }

    public  Map<String, Object> createOrder(Identify identify) {
        String ticket = getTicketFromCache();
        String token = getAccessTokenKeyFromCache();
//        String ticket = "chyvtGazRZvSjthyeLZRLPYE8h5yVcOclaLxAh7d8DGyLy3E03sCQRUcarKz47r9";
        String nonce = UUIDUtil.creatUUID();
//        String nonce = UUIDUtil.getNumber(32);
        List<String> values = new ArrayList<>();
        values.add(appId);
        values.add(String.valueOf(identify.getUserId()));
        values.add(nonce);
        values.add("1.0.0");
        String sign = sign(values, ticket);

        String url = "https://miniprogram-kyc.tencentcloudapi.com/api/server/getAdvFaceId?orderNo="+identify.getOrderNo();
        Map<String, Object> param = new HashMap<>();
        param.put("webankAppId", appId);
        param.put("orderNo", identify.getOrderNo());
        param.put("name", identify.getRealName());
        param.put("idNo", identify.getIdNumber());
        param.put("userId", identify.getUserId());
        param.put("version", "1.0.0");
        param.put("sign", sign);
        param.put("nonce", nonce);

        String result = HttpClient.doPostJson(param,null, url);
        System.out.println(result);
        JSONObject jsonObject = JSON.parseObject(result);
        if ("0".equalsIgnoreCase(jsonObject.getString("code"))) {
            Map<String, Object> out = jsonObject.getJSONObject("result").getInnerMap();
            String nonceTicket = getNonceTicket(identify.getUserId());
            if (StringUtils.isEmpty(nonceTicket)) {
                throw new RRException("签名失败");
            }
            out.put("nonce", nonce);
            out.put("sign", sign(values, nonceTicket));
            out.put("token", token);
            out.put("ticket", ticket);
            System.out.println(JSON.toJSONString(out));
            return out;
        } else {
            throw new RRException(jsonObject.getString("msg"));
        }
    }


    public static String sign(List<String> values, String ticket) {
        if (values == null) {
            throw new NullPointerException("values is null");
        }
        values.removeAll(Collections.singleton(null));// remove null
        values.add(ticket);
        System.out.println(Arrays.toString(values.toArray()));
        java.util.Collections.sort(values);
        StringBuilder sb = new StringBuilder();
        for (String s : values) {
            sb.append(s);
        }
        String result = Hashing.sha1().hashString(sb,
                Charsets.UTF_8).toString().toUpperCase();
        values.remove(ticket);
        return result;
    }
}
